namespace SimpleWebServices.Models
{
    using System;
    using System.Collections.Specialized;
    using System.Security.Principal;
    using System.Web;
    using System.Xml;
    using System.Xml.Serialization;
    using SimpleWebServices.Data;
    using SimpleWebServices.Web;
    using SimpleWebServices.Web.Mvc;
    using SimpleWebServices.Web.UI.Html;
    using SimpleWebServices.Web.UI.Html.Elements;

    [XmlRoot("container")]
    public sealed class TenantForm : FormContainer
    {
        [XmlIgnore]
        public FormSubmission Results
        {
            get;
            set;
        }

        public override void Complete(FormSession session)
        {
            if (null == session)
            {
                throw new ArgumentNullException("session");
            }

            HttpRequestBase request = HttpContextFactory.Current.Request;
            NameValueCollection variables = HttpContextFactory.Current.Request.ServerVariables;
            IIdentity user = HttpContextFactory.Current.User.Identity;

            this.Results = new FormSubmission
            {
                Urn = TenantForm.ToResultsUrn(session.Token.Value),
                Data = session.Data,
                Metadata =
                {
                    new Meta
                    {
                        Name = "Request.RawUrl",
                        Content = request.RawUrl
                    },
                    new Meta
                    {
                        Name = "Request.UrlReferrer",
                        Content = (null == request.UrlReferrer) ? string.Empty : request.UrlReferrer.OriginalString
                    },
                    new Meta
                    {
                        Name = "Request.UserAgent",
                        Content = request.UserAgent
                    },
                    new Meta
                    {
                        Name = "Server.MachineName",
                        Content = HttpContextFactory.Current.Server.MachineName
                    },
                    new Meta
                    {
                        Name = "User.Name",
                        Content = user.Name
                    },
                    new Meta
                    {
                        Name = "User.AuthenticationType",
                        Content = user.AuthenticationType
                    },
                    new Meta
                    {
                        Name = "User.IsAuthenticated",
                        Content = XmlConvert.ToString(user.IsAuthenticated)
                    },
                    new Meta
                    {
                        Name = "User.IP",
                        Content = variables["HTTP_X_FORWARDED_FOR"] ?? variables["REMOTE_ADDR"] ?? HttpContextFactory.Current.Request.UserHostAddress
                    }
                }
            };
            this.Results.Store();
            
            session.Data.Completed = true;
            session.Store();
        }

        public override T Template<T>()
        {
            AbsoluteUri urn = new TenantUriConverter(typeof(TenantFormController), "form").Urn;

            return Record.Retrieve<T>(urn);
        }

        private static AbsoluteUri ToResultsUrn(Token token)
        {
            string urn = new TenantUriConverter(typeof(TenantFormController), "form").Urn;

            return string.Concat(urn.Replace("/form/", "/submission/"), "/", token);
        }
    }
}